/**
 * 增强型Markdown渲染器组件
 * 支持代码高亮和复制功能
 */
import React, { useState } from 'react';
import { Box, IconButton, Paper, useTheme, alpha, styled } from '@mui/material';
import { Check as CheckIcon, ContentCopy as CopyIcon } from '@mui/icons-material';

// 代码块的样式
const CodeBlock = styled(Paper)(({ theme }) => ({
    backgroundColor: alpha(theme.palette.common.black, 0.05),
    padding: theme.spacing(1.5),
    borderRadius: theme.shape.borderRadius,
    fontFamily: '"Menlo", "Monaco", "Courier New", monospace',
    fontSize: '0.875rem',
    overflow: 'auto',
    position: 'relative',
    marginTop: theme.spacing(1),
    marginBottom: theme.spacing(1),
    border: `1px solid ${theme.palette.divider}`,
    '& pre': {
        margin: 0,
        padding: 0,
    },
    '& code': {
        fontFamily: '"Menlo", "Monaco", "Courier New", monospace',
        whiteSpace: 'pre',
    },
}));

// 代码块工具栏
const CodeBlockToolbar = styled(Box)(({ theme }) => ({
    position: 'absolute',
    top: theme.spacing(0.5),
    right: theme.spacing(0.5),
    display: 'flex',
    gap: theme.spacing(0.5),
    backgroundColor: alpha(theme.palette.background.paper, 0.8),
    borderRadius: theme.shape.borderRadius,
    padding: theme.spacing(0.25),
}));

interface MarkdownRendererProps {
    text: string;
}

/**
 * 增强型Markdown渲染器：支持代码高亮和复制功能
 */
const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({ text }) => {
    const theme = useTheme();
    const [copiedIndex, setCopiedIndex] = useState<number | null>(null);

    // 处理代码块复制
    const handleCopyCode = (code: string, index: number) => {
        navigator.clipboard.writeText(code);
        setCopiedIndex(index);
        setTimeout(() => setCopiedIndex(null), 2000);
    };

    // 识别代码块的正则表达式 - 改进对语言标记的支持
    const codeBlockRegex = /```([a-z]*)\n?([\s\S]*?)```/g;

    // 分割文本成代码块和普通文本
    const parts: { type: 'text' | 'code', content: string, language?: string }[] = [];
    let lastIndex = 0;
    let match;

    // 确保text是字符串
    const safeText = typeof text === 'string' ? text :
        (text && typeof text === 'object') ? String(text) : '';

    while ((match = codeBlockRegex.exec(safeText)) !== null) {
        // 添加代码块前的文本
        if (match.index > lastIndex) {
            parts.push({
                type: 'text',
                content: safeText.substring(lastIndex, match.index)
            });
        }

        // 添加代码块，包含语言信息
        parts.push({
            type: 'code',
            content: match[2].trim(),
            language: match[1].trim() || 'text'
        });

        lastIndex = match.index + match[0].length;
    }

    // 添加剩余的文本
    if (lastIndex < safeText.length) {
        parts.push({
            type: 'text',
            content: safeText.substring(lastIndex)
        });
    }

    // 如果没有找到代码块，将整个文本作为普通文本
    if (parts.length === 0) {
        parts.push({
            type: 'text',
            content: safeText
        });
    }

    // 基本的Markdown格式转换为HTML - 增强对各种格式的支持
    const renderTextPart = (md: string | unknown): string => {
        if (typeof md !== 'string') {
            return String(md || '');
        }

        // 处理有序列表和无序列表的容器
        let inOrderedList = false;
        let inUnorderedList = false;
        let result = md
            // 转义HTML特殊字符
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')

            // 标题
            .replace(/^# (.*?)$/gm, '<h1>$1</h1>')
            .replace(/^## (.*?)$/gm, '<h2>$1</h2>')
            .replace(/^### (.*?)$/gm, '<h3>$1</h3>')
            .replace(/^#### (.*?)$/gm, '<h4>$1</h4>')
            .replace(/^##### (.*?)$/gm, '<h5>$1</h5>')
            .replace(/^###### (.*?)$/gm, '<h6>$1</h6>')

            // 粗体和斜体
            .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
            .replace(/\*(.*?)\*/g, '<em>$1</em>')
            .replace(/__(.*?)__/g, '<strong>$1</strong>')
            .replace(/_(.*?)_/g, '<em>$1</em>')

            // 内联代码
            .replace(/`([^`]+)`/g, '<code>$1</code>')

            // 水平线
            .replace(/^---$/gm, '<hr />')
            .replace(/^___$/gm, '<hr />')
            .replace(/^\*\*\*$/gm, '<hr />')

            // 链接
            .replace(/\[(.*?)\]\((.*?)\)/g, '<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>')

            // 图片
            .replace(/!\[(.*?)\]\((.*?)\)/g, '<img src="$2" alt="$1" style="max-width:100%;height:auto;" />')

            // 引用
            .replace(/^> (.*?)$/gm, '<blockquote>$1</blockquote>')

            // 将每行变成一个数组元素，以便处理列表
            .split('\n');

        // 处理列表 - 使用更复杂的算法来正确嵌套列表
        let processedLines: string[] = [];
        let ulOpen = false;
        let olOpen = false;

        for (let i = 0; i < result.length; i++) {
            let line = result[i];

            // 无序列表项
            if (line.match(/^- (.*?)$/)) {
                if (!ulOpen) {
                    processedLines.push('<ul>');
                    ulOpen = true;
                }
                processedLines.push('<li>' + line.replace(/^- (.*?)$/, '$1') + '</li>');
            }
            // 有序列表项
            else if (line.match(/^[0-9]+\. (.*?)$/)) {
                if (!olOpen) {
                    processedLines.push('<ol>');
                    olOpen = true;
                }
                processedLines.push('<li>' + line.replace(/^[0-9]+\. (.*?)$/, '$1') + '</li>');
            }
            // 非列表项 - 关闭之前可能打开的列表
            else {
                if (ulOpen) {
                    processedLines.push('</ul>');
                    ulOpen = false;
                }
                if (olOpen) {
                    processedLines.push('</ol>');
                    olOpen = false;
                }
                processedLines.push(line);
            }
        }

        // 确保所有列表都被正确关闭
        if (ulOpen) {
            processedLines.push('</ul>');
        }
        if (olOpen) {
            processedLines.push('</ol>');
        }

        // 重新组合成字符串
        let html = processedLines.join('\n');

        // 修改段落处理逻辑，避免产生多余空行
        // 首先处理明确的双换行为段落分隔
        html = html.replace(/\n\s*\n/g, '</p><p>');

        // 然后处理单个换行，但保留列表和HTML标签的结构
        html = html.replace(/\n(?!<\/?(?:ul|ol|li|blockquote|h[1-6]|hr))/g, '<br />');

        // 将尚未包装在段落中的文本包装起来，但避免重复包装
        if (!html.trim().startsWith('<') && html.trim() !== '') {
            html = '<p>' + html.trim() + '</p>';
        }

        // 修复可能的嵌套段落问题
        html = html.replace(/<p><\/p>/g, '');

        return html;
    };

    return (
        <Box>
            {parts.map((part, index) => (
                part.type === 'code' ? (
                    <CodeBlock key={index} elevation={0}>
                        <CodeBlockToolbar>
                            {part.language && (
                                <Box
                                    sx={{
                                        fontSize: '0.7rem',
                                        color: 'text.secondary',
                                        padding: '3px 6px',
                                        backgroundColor: alpha(theme.palette.primary.main, 0.1),
                                        borderRadius: '3px',
                                        mr: 0.5
                                    }}
                                >
                                    {part.language}
                                </Box>
                            )}
                            <IconButton
                                size="small"
                                onClick={() => handleCopyCode(part.content, index)}
                                sx={{ fontSize: '0.75rem' }}
                            >
                                {copiedIndex === index ? <CheckIcon fontSize="inherit" /> : <CopyIcon fontSize="inherit" />}
                            </IconButton>
                        </CodeBlockToolbar>
                        <pre>
                            <code>{part.content}</code>
                        </pre>
                    </CodeBlock>
                ) : (
                    <Box
                        key={index}
                        className="markdown-content"
                        sx={{
                            '& code': {
                                backgroundColor: alpha(theme.palette.common.black, 0.05),
                                padding: '2px 4px',
                                borderRadius: '3px',
                                fontFamily: '"Menlo", "Monaco", "Courier New", monospace',
                                fontSize: '0.875rem',
                            },
                            '& a': {
                                color: theme.palette.primary.main,
                                textDecoration: 'none',
                                '&:hover': {
                                    textDecoration: 'underline',
                                },
                            },
                            '& blockquote': {
                                borderLeft: `4px solid ${theme.palette.divider}`,
                                margin: theme.spacing(1, 0),
                                padding: theme.spacing(0, 1),
                                color: theme.palette.text.secondary,
                            },
                            '& ul, & ol': {
                                paddingLeft: theme.spacing(3),
                                marginTop: theme.spacing(0.5),
                                marginBottom: theme.spacing(0.5),
                            },
                            '& li': {
                                marginBottom: theme.spacing(0.25),
                            },
                            '& h1, & h2, & h3, & h4, & h5, & h6': {
                                margin: theme.spacing(1, 0, 0.5, 0),
                                fontWeight: 500,
                                lineHeight: 1.2,
                            },
                            '& h1': { fontSize: '1.4rem' },
                            '& h2': { fontSize: '1.3rem' },
                            '& h3': { fontSize: '1.2rem' },
                            '& h4': { fontSize: '1.1rem' },
                            '& h5': { fontSize: '1rem' },
                            '& h6': { fontSize: '0.9rem' },
                            '& hr': {
                                border: 0,
                                borderTop: `1px solid ${theme.palette.divider}`,
                                margin: theme.spacing(1, 0),
                            },
                            '& img': {
                                maxWidth: '100%',
                                margin: theme.spacing(0.5, 0),
                            },
                            '& p': {
                                margin: theme.spacing(0.25, 0),
                                lineHeight: 1.5,
                            },
                            '& p + p': {
                                marginTop: theme.spacing(0.5),
                            },
                        }}
                        dangerouslySetInnerHTML={{ __html: renderTextPart(part.content) }}
                    />
                )
            ))}
        </Box>
    );
};

export default React.memo(MarkdownRenderer); 